///////////////////////////////////////////////////////////////////////////////
// Name:        src/aui/tabart.cpp
// Purpose:     wxaui: wx advanced user interface - notebook-art
// Author:      Benjamin I. Williams
// Modified by: Jens Lody (moved from auibook.cpp in extra file)
// Created:     2012-03-21
// RCS-ID:      $Id:$
// Copyright:   (C) Copyright 2006, Kirix Corporation, All Rights Reserved
// Licence:     wxWindows Library Licence, Version 3.1
///////////////////////////////////////////////////////////////////////////////

// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------

#include "wx/wxprec.h"

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#if wxUSE_AUI

#ifndef WX_PRECOMP
    #include "wx/dc.h"
    #include "wx/dcclient.h"
    #include "wx/settings.h"
    #include "wx/bitmap.h"
    #include "wx/menu.h"
#endif

#include "wx/renderer.h"
#include "./auibook.h"
#include "auiutils.h"

#include "wx/msw/uxtheme.h"
#include <tmschema.h>

#ifdef __WXMAC__
#include "wx/osx/private.h"
#endif


// -- GUI helper classes and functions --

class wxAuiCommandCapture : public wxEvtHandler
{
public:

    wxAuiCommandCapture() { m_lastId = 0; }
    int GetCommandId() const { return m_lastId; }

    bool ProcessEvent(wxEvent& evt)
    {
        if (evt.GetEventType() == wxEVT_COMMAND_MENU_SELECTED)
        {
            m_lastId = evt.GetId();
            return true;
        }

        if (GetNextHandler())
            return GetNextHandler()->ProcessEvent(evt);

        return false;
    }

private:
    int m_lastId;
};


// these functions live in dockart.cpp -- they'll eventually
// be moved to a new utility cpp file

wxBitmap wxAuiBitmapFromBits(const unsigned char bits[], int w, int h,
                             const wxColour& color);

wxString wxAuiChopText(wxDC& dc, const wxString& text, int max_size);

static void DrawButtons(wxDC& dc,
                        const wxRect& _rect,
                        const wxBitmap& bmp,
                        const wxColour& bkcolour,
                        int button_state)
{
    wxRect rect = _rect;

    if (button_state == wxAUI_BUTTON_STATE_PRESSED)
    {
        rect.x++;
        rect.y++;
    }

    if (button_state == wxAUI_BUTTON_STATE_HOVER ||
        button_state == wxAUI_BUTTON_STATE_PRESSED)
    {
        dc.SetBrush(wxBrush(bkcolour.ChangeLightness(120)));
        dc.SetPen(wxPen(bkcolour.ChangeLightness(75)));

        // draw the background behind the button
        dc.DrawRectangle(rect.x, rect.y, 15, 15);
    }

    // draw the button itself
    dc.DrawBitmap(bmp, rect.x, rect.y, true);
}

static void IndentPressedBitmap(wxRect* rect, int button_state)
{
    if (button_state == wxAUI_BUTTON_STATE_PRESSED)
    {
        rect->x++;
        rect->y++;
    }
}

// -- bitmaps --

#if defined( __WXMAC__ )
 static const unsigned char close_bits[]={
     0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFE, 0x03, 0xF8, 0x01, 0xF0, 0x19, 0xF3,
     0xB8, 0xE3, 0xF0, 0xE1, 0xE0, 0xE0, 0xF0, 0xE1, 0xB8, 0xE3, 0x19, 0xF3,
     0x01, 0xF0, 0x03, 0xF8, 0x0F, 0xFE, 0xFF, 0xFF };
#elif defined( __WXGTK__)
 static const unsigned char close_bits[]={
     0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xfb, 0xef, 0xdb, 0xed, 0x8b, 0xe8,
     0x1b, 0xec, 0x3b, 0xee, 0x1b, 0xec, 0x8b, 0xe8, 0xdb, 0xed, 0xfb, 0xef,
     0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
#else
 static const unsigned char close_bits[]={
     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xf3, 0xcf, 0xf9,
     0x9f, 0xfc, 0x3f, 0xfe, 0x3f, 0xfe, 0x9f, 0xfc, 0xcf, 0xf9, 0xe7, 0xf3,
     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
#endif

static const unsigned char left_bits[] = {
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x3f, 0xfe,
   0x1f, 0xfe, 0x0f, 0xfe, 0x1f, 0xfe, 0x3f, 0xfe, 0x7f, 0xfe, 0xff, 0xfe,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};

static const unsigned char right_bits[] = {
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x9f, 0xff, 0x1f, 0xff,
   0x1f, 0xfe, 0x1f, 0xfc, 0x1f, 0xfe, 0x1f, 0xff, 0x9f, 0xff, 0xdf, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};

static const unsigned char list_bits[] = {
		0xcc, 0xff,
		0x99, 0xff,
		0x33, 0xff,
		0x99, 0xff,
		0xcc, 0xff,
		0xff, 0xff,
		0xff, 0xff,
		0xff, 0xff,
		0xff, 0xff,
		0xff, 0xff,
		0xff, 0xff,
		0xff, 0xff,
		0xff, 0xff,
		0xff, 0xff,
		0xff, 0xff,
		0xff, 0xff,
};

/* XPM */
static char *tab_num_xpm[] = {
///* width height num_colors chars_per_pixel */
//"     5   60        2            1",
///* colors */
//"0 c #ffffff",
//"1 c #000000",
///* pixels */
"01100",
"10010",
"10010",
"10010",
"10010",
"01100",

"00100",
"11100",
"00100",
"00100",
"00100",
"00100",

"01100",
"10010",
"00010",
"01100",
"10000",
"11110",

"11100",
"00010",
"01100",
"00010",
"10010",
"01100",

"00100",
"01100",
"10100",
"11110",
"00100",
"00100",

"11110",
"10000",
"11100",
"00010",
"10010",
"01100",

"01110",
"10000",
"11100",
"10010",
"10010",
"01100",

"11110",
"00100",
"00100",
"01000",
"01000",
"01000",

"01100",
"10010",
"01100",
"10010",
"10010",
"01100",

"01100",
"10010",
"10010",
"01110",
"00010",
"11100"
};



// -- wxAuiGenericTabArt class implementation --

wxAuiGenericTabArt::wxAuiGenericTabArt()
{
    m_normalFont = *wxNORMAL_FONT;
    m_selectedFont = *wxNORMAL_FONT;
//    m_selectedFont.SetWeight(wxBOLD);
    m_measuringFont = m_selectedFont;

    m_tabCtrlHeight = 0;


    m_baseColour = wxAuiUtils::GetInstance()->m_base_colour;
    m_activeColour = m_baseColour.ChangeLightness(130);
    m_borderColour = wxAuiUtils::GetInstance()->m_border_colour;

    m_borderPen = wxPen(m_borderColour);
    m_baseColourPen = wxPen(m_baseColour);
    m_baseColourBrush = wxBrush(m_baseColour);

    m_activeCloseBmp = wxAuiBitmapFromBits(close_bits, 16, 16, *wxBLACK);
    m_disabledCloseBmp = wxAuiBitmapFromBits(close_bits, 16, 16, wxColour(128,128,128));

    m_activeLeftBmp = wxAuiBitmapFromBits(left_bits, 16, 16, *wxBLACK);
    m_disabledLeftBmp = wxAuiBitmapFromBits(left_bits, 16, 16, wxColour(128,128,128));

    m_activeRightBmp = wxAuiBitmapFromBits(right_bits, 16, 16, *wxBLACK);
    m_disabledRightBmp = wxAuiBitmapFromBits(right_bits, 16, 16, wxColour(128,128,128));

    m_activeWindowListBmp = wxAuiBitmapFromBits(list_bits, 16, 16, *wxBLACK);
    m_disabledWindowListBmp = wxAuiBitmapFromBits(list_bits, 16, 16, wxColour(128,128,128));

    m_flags = 0;
}

wxAuiGenericTabArt::~wxAuiGenericTabArt()
{
}

wxAuiTabArt* wxAuiGenericTabArt::Clone()
{
    return new wxAuiGenericTabArt(*this);
}

void wxAuiGenericTabArt::SetFlags(unsigned int flags)
{
    m_flags = flags;
}

void wxAuiGenericTabArt::SetSizingInfo(const wxSize& tab_ctrl_size,
                                       size_t tab_count)
{
    m_tabCtrlHeight = tab_ctrl_size.y;
}


void wxAuiGenericTabArt::DrawBackground(wxDC& dc,
                                        wxWindow* WXUNUSED(wnd),
                                        const wxRect& rect)
{
    // draw background

    wxColor top_color       = m_baseColour.ChangeLightness(96);
    wxColor bottom_color   = m_baseColour.ChangeLightness(130);
    wxRect r;

   if (m_flags &wxAUI_NB_BOTTOM)
       r = wxRect(rect.x, rect.y, rect.width+2, rect.height);
   // TODO: else if (m_flags &wxAUI_NB_LEFT) {}
   // TODO: else if (m_flags &wxAUI_NB_RIGHT) {}
   else //for wxAUI_NB_TOP
       r = wxRect(rect.x, rect.y, rect.width+2, rect.height-3);

    dc.GradientFillLinear(r, top_color, bottom_color, wxSOUTH);


   // draw base lines

   dc.SetPen(m_borderPen);
   int y = rect.GetHeight();
   int w = rect.GetWidth();

   if (m_flags &wxAUI_NB_BOTTOM)
   {
       dc.SetBrush(wxBrush(bottom_color));
       dc.DrawRectangle(-1, 0, w+2, 4);
   }
   // TODO: else if (m_flags &wxAUI_NB_LEFT) {}
   // TODO: else if (m_flags &wxAUI_NB_RIGHT) {}
   else //for wxAUI_NB_TOP
   {
       dc.SetBrush(m_activeColour);
       dc.DrawRectangle(-1, y-4, w+2, 4);
   }
}

// DrawTab() draws an individual tab.
//
// dc       - output dc
// in_rect  - rectangle the tab should be confined to
// caption  - tab's caption
// active   - whether or not the tab is active
// out_rect - actual output rectangle
// x_extent - the advance x; where the next tab should start

void wxAuiGenericTabArt::DrawTab(wxDC& dc,
                                 wxWindow* wnd,
                                 const wxAuiNotebookPage& page,
                                 const wxRect& in_rect,
                                 int close_button_state,
                                 wxRect* out_tab_rect,
                                 wxRect* out_button_rect,
                                 int* x_extent)
{
    wxCoord normal_textx, normal_texty;
    wxCoord selected_textx, selected_texty;
    wxCoord texty;

    // if the caption is empty, measure some temporary text
    wxString caption = page.caption;
    if (caption.empty())
        caption = wxT("Xj");

    dc.SetFont(m_selectedFont);
    dc.GetTextExtent(caption, &selected_textx, &selected_texty);

    dc.SetFont(m_normalFont);
    dc.GetTextExtent(caption, &normal_textx, &normal_texty);

    // figure out the size of the tab
    wxSize tab_size = GetTabSize(dc,
                                 wnd,
                                 page.caption,
                                 page.bitmap,
                                 page.active,
                                 close_button_state,
                                 x_extent);

    wxCoord tab_height = m_tabCtrlHeight-3;
    if (!page.active)
    {
    	tab_height -= 1;
    }
    wxCoord tab_width = tab_size.x-2;
    wxCoord tab_x = in_rect.x;
    wxCoord tab_y = in_rect.y + in_rect.height - tab_height;


    caption = page.caption;


    // select pen, brush and font for the tab to be drawn

    if (page.active)
    {
        dc.SetFont(m_selectedFont);
        texty = selected_texty;
    }
    else
    {
        dc.SetFont(m_normalFont);
        texty = normal_texty;
    }


    // create points that will make the tab outline

    int clip_width = tab_width;
    if (tab_x + clip_width > in_rect.x + in_rect.width)
        clip_width = (in_rect.x + in_rect.width) - tab_x;

    // since the above code above doesn't play well with WXDFB or WXCOCOA,
    // we'll just use a rectangle for the clipping region for now --
    dc.SetClippingRegion(tab_x, tab_y, clip_width+1, tab_height-3);


		wxPoint border_points[6];
		if (m_flags &wxAUI_NB_BOTTOM)
		{
			border_points[0] = wxPoint(tab_x,             tab_y);
			border_points[1] = wxPoint(tab_x,             tab_y+tab_height-6);
			border_points[2] = wxPoint(tab_x+2,           tab_y+tab_height-4);
			border_points[3] = wxPoint(tab_x+tab_width-2, tab_y+tab_height-4);
			border_points[4] = wxPoint(tab_x+tab_width,   tab_y+tab_height-6);
			border_points[5] = wxPoint(tab_x+tab_width,   tab_y);
		}
		else //if (m_flags & wxAUI_NB_TOP) {}
		{
			border_points[0] = wxPoint(tab_x,             tab_y+tab_height-4);
			border_points[1] = wxPoint(tab_x,             tab_y+2);
			border_points[2] = wxPoint(tab_x+2,           tab_y);
			border_points[3] = wxPoint(tab_x+tab_width-2, tab_y);
			border_points[4] = wxPoint(tab_x+tab_width,   tab_y+2);
			border_points[5] = wxPoint(tab_x+tab_width,   tab_y+tab_height-4);
		}
		// TODO: else if (m_flags &wxAUI_NB_LEFT) {}
		// TODO: else if (m_flags &wxAUI_NB_RIGHT) {}

		int drawn_tab_yoff = border_points[1].y;
		int drawn_tab_height = border_points[0].y - border_points[1].y;

#if wxUSE_UXTHEME
    wxUxThemeHandle hTheme(wnd, L"TAB");
    wxRect tbrect = wxRect(tab_x, tab_y, tab_width+1, tab_height-4);
    if(page.active)
    {
    	tbrect.height+=2;
    }
    if(hTheme)
    {
    	RECT r;
    	wxCopyRectToRECT(tbrect, r);
    	if(page.active)
    	{
			wxUxThemeEngine::Get()->DrawThemeBackground(hTheme,
							GetHdcOf(dc.GetTempHDC()), TABP_TOPTABITEM, TTIS_SELECTED, &r, NULL);
    	}
    	else
    	{
			wxUxThemeEngine::Get()->DrawThemeBackground(hTheme,
							GetHdcOf(dc.GetTempHDC()), TABP_TOPTABITEM, TTIS_NORMAL, &r, NULL);
    	}
    }
    else
#endif
    {
		if (page.active)
		{
			wxRect r(tab_x+1, tab_y+1, tab_width-1, tab_height-4);
			dc.GradientFillLinear(r,m_activeColour.ChangeLightness(190).ChangeLightness(190),m_activeColour,wxSOUTH);
		}
		else
		{
			wxRect r(tab_x, tab_y+1, tab_width, tab_height-3);
			r.x += 1;
			r.y++;
			r.width -= 2;

			// -- draw top gradient fill for glossy look
			wxColor top_color = m_baseColour.ChangeLightness(99);
			wxColor bottom_color = top_color.ChangeLightness(97);
			dc.GradientFillLinear(r, bottom_color, top_color, wxNORTH);
			dc.SetPen(wxColour(m_baseColour.ChangeLightness(86)));
			dc.DrawLine(border_points[4].x-1  ,border_points[4].y-1,
						border_points[5].x-1  ,border_points[5].y);
			dc.SetPen(wxColour(m_baseColour.ChangeLightness(120)));
			dc.DrawLine(border_points[0].x+1  ,border_points[0].y-1,
						border_points[1].x+1  ,border_points[1].y-1);
			dc.DrawLine(border_points[2].x  ,border_points[2].y+1,
						border_points[3].x-1  ,border_points[3].y+1);

		}

		wxColour border_color = m_borderColour;
		if(page.active)
		{
			border_color = border_color.ChangeLightness(80);
		}
		// draw tab outline
		dc.SetPen(border_color);
		dc.SetBrush(*wxTRANSPARENT_BRUSH);
		dc.DrawPolygon(WXSIZEOF(border_points), border_points);

		dc.SetPen(border_color.ChangeLightness(110));
		dc.DrawPoint(border_points[1]);
		dc.DrawPoint(border_points[2]);
		dc.DrawPoint(border_points[3]);
		dc.DrawPoint(border_points[4]);
		dc.SetPen(border_color.ChangeLightness(160));
		dc.DrawPoint(border_points[1].x+1,border_points[1].y-1);
		if(page.active)
		dc.DrawPoint(border_points[4].x-1,border_points[4].y-1);

		dc.SetPen(border_color.ChangeLightness(130));
		dc.DrawPoint(border_points[1].x  ,border_points[1].y-1);
		dc.DrawPoint(border_points[2].x-1,border_points[2].y  );
		dc.DrawPoint(border_points[3].x+1,border_points[3].y  );
		dc.DrawPoint(border_points[4].x  ,border_points[4].y-1);

//		dc.SetPen(wxColour("RED")/*border_color.ChangeLightness(180)*/);
//		dc.DrawPoint(border_points[1].x+1,border_points[1].y  );
//		dc.DrawPoint(border_points[2].x  ,border_points[2].y+1);

		// there are two horizontal grey lines at the bottom of the tab control,
		// this gets rid of the top one of those lines in the tab control
		if (page.active)
		{
			if (m_flags &wxAUI_NB_BOTTOM)
				dc.SetPen(wxPen(m_baseColour.ChangeLightness(170)));
			// TODO: else if (m_flags &wxAUI_NB_LEFT) {}
			// TODO: else if (m_flags &wxAUI_NB_RIGHT) {}
			else //for wxAUI_NB_TOP
				dc.SetPen(wxPen(m_activeColour));
			dc.DrawLine(border_points[0].x+1,
						border_points[0].y,
						border_points[5].x,
						border_points[5].y);
		}

    }
    int text_offset = tab_x + 8;
    int close_button_width = 0;
    if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN)
    {
        close_button_width = m_activeCloseBmp.GetWidth();
    }

    int bitmap_offset = 0;
    if (page.bitmap.IsOk())
    {
        bitmap_offset = tab_x + 8;

        // draw bitmap
        dc.DrawBitmap(page.bitmap,
                      bitmap_offset,
                      drawn_tab_yoff + (drawn_tab_height/2) - (page.bitmap.GetHeight()/2),
                      true);

        text_offset = bitmap_offset + page.bitmap.GetWidth();
        text_offset += 3; // bitmap padding

    }
    else
    {
        text_offset = tab_x + 8;
    }


    wxString draw_text = wxAuiChopText(dc,
                          caption,
                          tab_width - (text_offset-tab_x) - close_button_width);

    // draw tab text
    dc.DrawText(draw_text,
                text_offset,
                drawn_tab_yoff + (drawn_tab_height)/2 - (texty/2) - 1);

    // draw focus rectangle
//    if (page.active && (wnd->FindFocus() == wnd))
//    {
//        wxRect focusRectText(text_offset, (drawn_tab_yoff + (drawn_tab_height)/2 - (texty/2) - 1),
//            selected_textx, selected_texty);
//
//        wxRect focusRect;
//        wxRect focusRectBitmap;
//
//        if (page.bitmap.IsOk())
//            focusRectBitmap = wxRect(bitmap_offset, drawn_tab_yoff + (drawn_tab_height/2) - (page.bitmap.GetHeight()/2),
//                                            page.bitmap.GetWidth(), page.bitmap.GetHeight());
//
//        if (page.bitmap.IsOk() && draw_text.IsEmpty())
//            focusRect = focusRectBitmap;
//        else if (!page.bitmap.IsOk() && !draw_text.IsEmpty())
//            focusRect = focusRectText;
//        else if (page.bitmap.IsOk() && !draw_text.IsEmpty())
//            focusRect = focusRectText.Union(focusRectBitmap);
//
//        focusRect.Inflate(2, 2);
//
//        wxRendererNative::Get().DrawFocusRect(wnd, dc, focusRect, 0);
//    }

    // draw close button if necessary
    if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN)
    {
        wxBitmap bmp = m_disabledCloseBmp;

        if (close_button_state == wxAUI_BUTTON_STATE_HOVER ||
            close_button_state == wxAUI_BUTTON_STATE_PRESSED)
        {
            bmp = m_activeCloseBmp;
        }

        int offsetY = tab_y-1;
        if (m_flags & wxAUI_NB_BOTTOM)
            offsetY = 1;

        wxRect rect(tab_x + tab_width - close_button_width - 1,
                    offsetY + (tab_height/2) - (bmp.GetHeight()/2),
                    close_button_width,
                    tab_height);

        IndentPressedBitmap(&rect, close_button_state);
        dc.DrawBitmap(bmp, rect.x, rect.y, true);

        *out_button_rect = rect;
    }

    *out_tab_rect = wxRect(tab_x, tab_y, tab_width, tab_height);

    dc.DestroyClippingRegion();
}

int wxAuiGenericTabArt::GetIndentSize()
{
    return 2;
}

wxSize wxAuiGenericTabArt::GetTabSize(wxDC& dc,
                                      wxWindow* WXUNUSED(wnd),
                                      const wxString& caption,
                                      const wxBitmap& bitmap,
                                      bool WXUNUSED(active),
                                      int close_button_state,
                                      int* x_extent)
{
    wxCoord measured_textx, measured_texty, tmp;

    dc.SetFont(m_measuringFont);
    dc.GetTextExtent(caption, &measured_textx, &measured_texty);

    dc.GetTextExtent(wxT("ABCDEFXj"), &tmp, &measured_texty);

    // add padding around the text
    wxCoord tab_width = measured_textx;
    wxCoord tab_height = measured_texty;

    // if the close button is showing, add space for it
    if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN)
        tab_width += m_activeCloseBmp.GetWidth() + 3;

    // if there's a bitmap, add space for it
    if (bitmap.IsOk())
    {
        tab_width += bitmap.GetWidth();
        tab_width += 3; // right side bitmap padding
        tab_height = wxMax(tab_height, bitmap.GetHeight());
    }

    // add padding
    tab_width += 16;
    tab_height += 10;

    *x_extent = tab_width;

    return wxSize(tab_width, tab_height);
}


void wxAuiGenericTabArt::DrawNumber(wxDC& dc,int x, int y, int num)
{
	wxString str;
	str.Printf("%d",num);
	for(size_t index=0;index<str.length();index++)
	{
		wxUniChar ch = str.GetChar(index);
		if(ch>='0'&&ch<='9')
		{
			dc.SetPen(*wxBLACK_PEN);
			for(int h=0;h<6;h++)
			{
				char * line_ptr = tab_num_xpm[(ch-'0')*6+h];

				for(int w=0;w<5;w++)
				{
					if(line_ptr[w]=='1')
						dc.DrawPoint(x+index*5+w,y+h);
				}
			}
		}
	}
}

void wxAuiGenericTabArt::DrawTabListButton(wxDC& dc,const wxRect& inRect,int status, int hide_num)
{
	wxRect rect = inRect;
	rect.x +=2;
	rect.width -=2;
	if(wxAUI_BUTTON_STATE_HOVER==status ||wxAUI_BUTTON_STATE_PRESSED==status)
	{
		wxColour bc = wxAuiUtils::GetInstance()->m_border_colour;
		dc.SetPen(wxPen(bc));
		dc.SetBrush(wxBrush(wxColour(255,255,255)));
		dc.DrawRectangle(rect);
		dc.SetPen(wxPen(bc.ChangeLightness(150)));
		dc.DrawPoint(rect.x,rect.y);dc.DrawPoint(rect.x+rect.width-1,rect.y);
		dc.SetPen(wxPen(bc.ChangeLightness(170)));
		dc.DrawPoint(rect.x,rect.y+rect.height-1);dc.DrawPoint(rect.x+rect.width-1,rect.y+rect.height-1);
	}
	int x = rect.x+4;
	int y = rect.y+4;
	wxBitmap bmp = m_activeWindowListBmp;
	dc.DrawBitmap(bmp, x, y, true);
	DrawNumber(dc,x+8,y+5,hide_num);
}
int wxAuiGenericTabArt::GetTabListButtonWidth(int pages_cnt)
{
	int num_char_width = 5;
	int w = 8;
	w += 8;
	if(pages_cnt>=0)
		w += num_char_width;
    if(pages_cnt>=10)
    	w += num_char_width;
    if(pages_cnt>=100)
    	w += num_char_width;
    if(pages_cnt>=1000)
    	w += num_char_width;
    if(pages_cnt>=10000)
    	w += num_char_width;
    if(pages_cnt>=100000)
    	w += num_char_width;
	w += 2;

	return w;
}


void wxAuiGenericTabArt::DrawButton(wxDC& dc,
                                    wxWindow* WXUNUSED(wnd),
                                    const wxRect& in_rect,
                                    int bitmap_id,
                                    int button_state,
                                    int orientation,
                                    wxRect* out_rect)
{
    wxBitmap bmp;
    wxRect rect;

    switch (bitmap_id)
    {
        case wxAUI_BUTTON_CLOSE:
            if (button_state & wxAUI_BUTTON_STATE_DISABLED)
                bmp = m_disabledCloseBmp;
            else
                bmp = m_activeCloseBmp;
            break;
        case wxAUI_BUTTON_LEFT:
            if (button_state & wxAUI_BUTTON_STATE_DISABLED)
                bmp = m_disabledLeftBmp;
            else
                bmp = m_activeLeftBmp;
            break;
        case wxAUI_BUTTON_RIGHT:
            if (button_state & wxAUI_BUTTON_STATE_DISABLED)
                bmp = m_disabledRightBmp;
            else
                bmp = m_activeRightBmp;
            break;
        case wxAUI_BUTTON_WINDOWLIST:
            if (button_state & wxAUI_BUTTON_STATE_DISABLED)
                bmp = m_disabledWindowListBmp;
            else
                bmp = m_activeWindowListBmp;
            break;
    }


    if (!bmp.IsOk())
        return;

    rect = in_rect;

    if (orientation == wxLEFT)
    {
        rect.SetX(in_rect.x);
        rect.SetY(((in_rect.y + in_rect.height)/2) - (bmp.GetHeight()/2));
        rect.SetWidth(bmp.GetWidth());
        rect.SetHeight(bmp.GetHeight());
    }
    else
    {
        rect = wxRect(in_rect.x + in_rect.width - bmp.GetWidth(),
                      ((in_rect.y + in_rect.height)/2) - (bmp.GetHeight()/2),
                      bmp.GetWidth(), bmp.GetHeight());
    }

    IndentPressedBitmap(&rect, button_state);
    dc.DrawBitmap(bmp, rect.x, rect.y, true);

    *out_rect = rect;
}

int wxAuiGenericTabArt::ShowDropDown(wxWindow* wnd,
		                             wxPoint &pt,
                                     const wxAuiNotebookPageArray& pages,
                                     int /*active_idx*/)
{
    wxMenu menuPopup;

    size_t i, count = pages.GetCount();
    for (i = 0; i < count; ++i)
    {
        const wxAuiNotebookPage& page = pages.Item(i);
        wxString caption = page.caption;

        // if there is no caption, make it a space.  This will prevent
        // an assert in the menu code.
        if (caption.IsEmpty())
            caption = wxT(" ");

        wxMenuItem* item = new wxMenuItem(NULL, 1000+i, caption);
        if (page.bitmap.IsOk())
            item->SetBitmap(page.bitmap);
        menuPopup.Append(item);
    }

//    // find out where to put the popup menu of window items
//    wxPoint pt = ::wxGetMousePosition();
//    pt = wnd->ScreenToClient(pt);
//
//    // find out the screen coordinate at the bottom of the tab ctrl
//    wxRect cli_rect = wnd->GetClientRect();
//    pt.y = cli_rect.y + cli_rect.height;

    wxAuiCommandCapture* cc = new wxAuiCommandCapture;
    wnd->PushEventHandler(cc);
    wnd->PopupMenu(&menuPopup, pt);
    int command = cc->GetCommandId();
    wnd->PopEventHandler(true);

    if (command >= 1000)
        return command-1000;

    return -1;
}

int wxAuiGenericTabArt::GetBestTabCtrlSize(wxWindow* wnd,
                                           const wxAuiNotebookPageArray& pages,
                                           const wxSize& requiredBmp_size)
{
    wxClientDC dc(wnd);
    dc.SetFont(m_measuringFont);

    // sometimes a standard bitmap size needs to be enforced, especially
    // if some tabs have bitmaps and others don't.  This is important because
    // it prevents the tab control from resizing when tabs are added.
    wxBitmap measureBmp;
    if (requiredBmp_size.IsFullySpecified())
    {
        measureBmp.Create(requiredBmp_size.x,
                           requiredBmp_size.y);
    }


    int max_y = 0;
    size_t i, page_count = pages.GetCount();
    for (i = 0; i < page_count; ++i)
    {
        wxAuiNotebookPage& page = pages.Item(i);

        wxBitmap bmp;
        if (measureBmp.IsOk())
            bmp = measureBmp;
        else
            bmp = page.bitmap;

        // we don't use the caption text because we don't
        // want tab heights to be different in the case
        // of a very short piece of text on one tab and a very
        // tall piece of text on another tab
        int x_ext = 0;
        wxSize s = GetTabSize(dc,
                              wnd,
                              wxT("ABCDEFGHIj"),
                              bmp,
                              true,
                              wxAUI_BUTTON_STATE_HIDDEN,
                              &x_ext);

        max_y = wxMax(max_y, s.y);
    }

    return max_y+2;
}

void wxAuiGenericTabArt::SetNormalFont(const wxFont& font)
{
    m_normalFont = font;
}

void wxAuiGenericTabArt::SetSelectedFont(const wxFont& font)
{
    m_selectedFont = font;
}

void wxAuiGenericTabArt::SetMeasuringFont(const wxFont& font)
{
    m_measuringFont = font;
}

void wxAuiGenericTabArt::SetColour(const wxColour& colour)
{
    m_baseColour = colour;
    m_borderPen = wxPen(m_baseColour.ChangeLightness(75));
    m_baseColourPen = wxPen(m_baseColour);
    m_baseColourBrush = wxBrush(m_baseColour);
}

void wxAuiGenericTabArt::SetActiveColour(const wxColour& colour)
{
    m_activeColour = colour;
}

#endif // wxUSE_AUI
